package com.ruoyi.weiriya.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.hash.Hash;
import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WMember;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.weiriya.service.IWCompanyService;
import com.ruoyi.weiriya.service.IWMemberService;
import com.ruoyi.weiriya.service.IWUserAreaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.weiriya.mapper.WMessageMapper;
import com.ruoyi.weiriya.domain.WMessage;
import com.ruoyi.weiriya.service.IWMessageService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 平台消息推送管理Service业务层处理
 * 
 * @author lynn
 * @date 2023-08-01
 */
@Slf4j
@Service
public class WMessageServiceImpl extends ServiceImpl<WMessageMapper, WMessage> implements IWMessageService
{

    @Autowired
    private WMessageMapper messageMapper;

    @Autowired
    private IWMemberService wMemberService;

    @Autowired
    private IWCompanyService companyService;

    @Override
    public boolean saveWMessage(WMessage wMessage) {
        Long userId = SecurityUtils.getUserId();

        Integer messageRange = wMessage.getMessageRange();
        String memberId = wMessage.getMemberId();
        String areaId = wMessage.getAreaId();

        // 保存记录
        wMessage.setUserType(1);
        wMessage.setReplyUserId(userId.toString());
        this.save(wMessage);

        // 判断发送用户范围
        if(messageRange == 2){
            // 全部用户
            ThreadUtil.execAsync(() -> {
                // 获取全部用户ID
//                long count = wMemberService.count();
                List<String> memberIds = wMemberService.list().stream().map(WMember::getId).collect(Collectors.toList());
                initMsgAndSave(wMessage, memberIds);
            });

        }else if(messageRange == 1){
            // 指定用户
            if(StringUtils.isBlank(memberId)){
                throw new ServiceException("请选择发送的用户！");
            }
            String[] memberIds = memberId.split(",");
            List<String> ids = Arrays.asList(memberIds);
            ThreadUtil.execAsync(() -> {
                System.out.println("进来了");
                // 获取全部用户ID
                initMsgAndSave(wMessage, ids);
            });
        }else if(messageRange == 3){
            // 指定用户
            if(StringUtils.isBlank(areaId)){
                throw new ServiceException("请选择发送的区域！");
            }
            String[] areaIds = areaId.split(",");
            List<String> ids = Arrays.asList(areaIds);

            ThreadUtil.execAsync(() -> {
                List<String> memberIds = wMemberService.list(new LambdaQueryWrapper<WMember>()
                        .in(WMember::getAreaId, ids)).stream().map(WMember::getId).collect(Collectors.toList());
                // 获取全部用户ID
                initMsgAndSave(wMessage, memberIds);
            });
        }else {
            throw new ServiceException("请指定发送范围！");
        }
        return true;
    }

    @Override
    public List<WMessage> getList(WMessage wMessage) {
        String openId = SecurityUtils.getLoginUser().getOpenId();
        // 用户
        if(StringUtils.isNotBlank(openId)){
            wMessage.setMemberId(SecurityUtils.getUserId().toString());
            wMessage.setUserType(2);
            return messageMapper.getList(wMessage.queryWrapper());
        } else {
            // 管理员
            wMessage.setUserType(1);
            QueryWrapper<WMessage> queryWrapper = wMessage.queryWrapper();
            if(StringUtils.isNotBlank(SecurityUtils.getLoginUser().getUser().getCompanyId())){
                List<String> areaIdListByUserId = companyService.getAreaIdList();
                if(areaIdListByUserId.size() > 0) {
                    queryWrapper.in("msg.area_id", areaIdListByUserId);
                } else {
                    return new ArrayList<>();
                }
            }
            return messageMapper.getList(queryWrapper);
        }
    }

    @Override
    public WMessage getWMessageById(String id) {
        return messageMapper.getWMessageById(id);
    }

    @Override
    public List<Map<String, String>> statistical() {
        List<Map<String, String>> list = new ArrayList<>();

        for (int i = 1; i < 4; i++) {
            long count = this.count(new LambdaQueryWrapper<WMessage>()
                    .eq(WMessage::getMemberId, SecurityUtils.getUserId())
                    .eq(WMessage::getMessageType, i)
                    .eq(WMessage::getState, 1)
                    .eq(WMessage::getUserType, 2));
            WMessage one = this.getOne(new LambdaQueryWrapper<WMessage>()
                    .eq(WMessage::getMemberId, SecurityUtils.getUserId())
                    .eq(WMessage::getMessageType, i)
                    .orderByDesc(WMessage::getCreateTime)
                    .last("LIMIT 1"));
            Map<String, String> map = new HashMap<>();
            map.put("type", i + "");
            map.put("count", count + "");
            map.put("title", StringUtils.isNull(one) ? "" : one.getMessageTitle());

            list.add(map);
        }
        return list;
    }

    @Override
    public void remind(WMember member, Double d) {
        WMessage message = new WMessage();
        message.setMessageTitle("余额不足提醒");
        message.setMessageContent("您的余额已不足：" + d + "元，为避免无法停车或充电，请及时充值！\n 当前余额：" + member.getWallet());
        message.setAreaId(member.getAreaId());
        message.setMessageType(1);
        message.setMessageRange(1);
        message.setMemberId(member.getId());
        message.setState(1);
        message.setUserType(2);
        message.setCreateTime(new Date());
        message.setCreateBy("1");
        message.setUpdateTime(new Date());
        message.setUpdateBy("1");
        this.save(message);
        log.info("余额不足提醒成功！");
    }

    @Override
    public String getStateById(String id) {
        List<WMessage> list = this.list(new LambdaQueryWrapper<WMessage>().eq(WMessage::getParentId, id));
        if(list.size() == 0){
            WMessage byId = this.getById(id);
            if(byId.getState() == 2){
                return "已读";
            }else {
                return "未读";
            }
        }
        int count = list.size();
        int readCount = 0;
        for (WMessage message : list) {
            if(message.getState() == 2){
                readCount ++;
            }
        }
        return "已读数量："  + readCount + "/" + count;
    }

    private void initMsgAndSave(WMessage wMessage, List<String> ids) {
        List<WMessage> wMessages = new ArrayList<>(ids.size());
        for (String id : ids) {
            WMessage messages = new WMessage();
            messages.setMessageRange(1);
            messages.setMessageTitle(wMessage.getMessageTitle());
            messages.setMessageContent(wMessage.getMessageContent());
            messages.setMessageType(wMessage.getMessageType());
            messages.setParentId(wMessage.getId());
            messages.setReplyUserId(wMessage.getReplyUserId());
            messages.setState(1);
            messages.setUserType(2);
            messages.setMemberId(id);
            messages.setCreateBy("1");
            messages.setCreateTime(new Date());
            messages.setUpdateBy("1");
            messages.setUpdateTime(new Date());
            wMessages.add(messages);
        }
        try {
            boolean b = this.saveBatch(wMessages);
        }catch (Exception e){
            System.out.println(e);
        }
    }

}
